(function(global){
'use strict';

var XUI = {};
global.XUI = XUI;

XUI.setStyle = function(element, styles) {
    for(var s in styles) {
        element.style[s] = styles[s];
    }
};

/**
 * 通用遮罩层
 */
XUI.lock = function() {
    var XLock = function() {
        this.doc = document;

        this.zIndex = 1100;
        this.mask = null;
        this.id = 'x-mask';

        this.init();
    };
    XLock.prototype = {
        constructor : XLock
        ,init : function() {
            this.mask = this.doc.createElement('div');
            this.mask.setAttribute('id', this.id);

            XUI.setStyle(this.mask, {
                position: 'fixed',
                zIndex: this.zIndex,
                width: '100%',
                height: '100%',
                top: 0,
                left: 0,
                backgroundColor: 'rgba(0, 0, 0, .5)'
            });
        }

        // api
        ,unLock : function() {
            if(null !== this.doc.getElementById(this.id)) {
                this.doc.body.removeChild(this.mask);
            }
        }
        ,lock : function() {
            if(null === this.doc.getElementById(this.id)) {
                this.doc.body.appendChild(this.mask);
            }
        }
    };

    return new XLock();
}();

/**
 * toast
 */
XUI.toast = function() {
    var XToast = function() {
        this.doc = document;
        this.wrapper = null;
        this.callback = null;
        this.duration = 2000;
        this.timer = 0;
        this.zIndex = 1120;
        this.id = 'x-toast';

        this.successIcon = '';
        this.errorIcon = '';
    };
    XToast.prototype = {
        constructor: XToast,
        init : function() {
            if(null === this.wrapper) {
                this.wrapper = this.doc.createElement('div');
                this.wrapper.setAttribute('id', this.id);
            }

            XUI.setStyle(this.wrapper, {
                position: 'fixed',
                zIndex: this.zIndex,
                top: '20%',
                minWidth: '180px',
                padding: '46px 10px 20px 10px',
                fontSize: '14px',
                fontWeight: 'bold',
                textAlign: 'center',
                borderRadius: '4px',
                transition: 'top .2s linear'
            });
        },
        resetPosition: function() {
            var _self = this;
            var width = this.wrapper.clientWidth;
            var winWidth = this.doc.body.clientWidth;

            this.wrapper.style.left = Math.floor((winWidth - width) / 2) + 'px';

            setTimeout(function(){
                _self.wrapper.style.top = '22%';

                _self = null;
            }, 10);
        },
        render: function() {
            var _self = this;

            if(null === this.doc.getElementById(this.id)) {
                this.doc.body.appendChild(this.wrapper);
            }

            clearTimeout(this.timer);
            this.timer = setTimeout(function(){
                _self.close();

                if(null !== _self.callback) {
                    _self.callback();
                }

            }, this.duration);
        },
        close: function() {
            if(null !== this.doc.getElementById(this.id)) {
                this.doc.body.removeChild(this.wrapper);
            }

            this.wrapper = null;

            // XUI.lock.unLock();
        },
        success: function(msg, callback, duration) {
            if(undefined !== callback) {
                this.callback = callback;
            }
            if(undefined !== duration) {
                this.duration = duration;
            }

            this.init();
            XUI.setStyle(this.wrapper, {
                color: 'green',
                background: '#edffe9 url('+ this.successIcon +') no-repeat center 6px',
                borderStyle: 'solid',
                borderWidth: '3px 1px 1px 1px',
                borderColor: 'green #dcf9d6 #dcf9d6 #dcf9d6'
            });
            this.wrapper.innerHTML = msg;
            this.render();
            this.resetPosition();
        },
        error: function(msg, callback, duration) {
            if(undefined !== callback) {
                this.callback = callback;
            }
            if(undefined !== duration) {
                this.duration = duration;
            }

            this.init();
            XUI.setStyle(this.wrapper, {
                color: '#ea4a36',
                background: '#fff2f2 url('+ this.errorIcon +') no-repeat center 6px',
                borderStyle: 'solid',
                borderWidth: '3px 1px 1px 1px',
                borderColor: '#ea4a36 #ffe3e0 #ffe3e0 #ffe3e0'
            });
            this.wrapper.innerHTML = msg;
            this.render();
            this.resetPosition();
        }
    };

    return new XToast();
}();

/**
 * dialog
 */
XUI.dialog = function() {
    var XDialog = function() {
        this.doc = document;

        this.id = 'xui-dialog';
        this.zIndex = 1120;

        this.wrapper = null;
        this.header = null;
        this.content = null;
        this.footer = null;
        this.cancelButton = null;
        this.okButton = null;
        this.closeButton = null;

        this.callback = null;
        this.onContentClick = null;

        this.defaultConfigs = {
            dialogWidth: 220,
            okButtonText: '确定',
            cancelButtonText: '取消',
            okButtonStyle: null,
            cancelButtonStyle: null
        };
    };
    XDialog.BTN_NONE = 0;
    XDialog.BTN_OK = 1;
    XDialog.BTN_CANCEL = 2;
    XDialog.prototype = {
        extend: function(src, configs) {
            for(var k in configs) {
                src[k] = configs[k];
            }

            return src;
        },
        constructor: XDialog,
        init: function(msg, title, type, configs) {
            var conf = this.extend({}, this.defaultConfigs);

            if(undefined === title) {
                title = '提示';
            }
            if(undefined !== configs) {
                for(var k in configs) {
                    conf[k] = configs[k];
                }
            }

            // wrapper
            this.wrapper = this.doc.createElement('div');
            this.wrapper.setAttribute('id', this.id);
            XUI.setStyle(this.wrapper, {
                position: 'fixed',
                zIndex: this.zIndex,
                top: '10%',
                width: conf.dialogWidth + 'px',
                fontSize: '14px',
                backgroundColor: '#fff',
                borderRadius: '5px',
                transition: 'top .2s linear'
            });

            // close
            this.closeButton = this.doc.createElement('span');
            this.closeButton.setAttribute('data-role', 'close');
            XUI.setStyle(this.closeButton, {
                position: 'absolute',
                width: '20px',
                height: '20px',
                lineHeight: '18px',
                top: '8px',
                right: '8px',
                textAlign: 'center',
                fontSize: '20px',
                cursor: 'pointer'
            });
            this.closeButton.innerHTML = '&times;';

            // header
            this.header = this.doc.createElement('div');
            XUI.setStyle(this.header, {
                width: '80%',
                height: '50px',
                lineHeight: '50px',
                textIndent: '10px',
                textAlign: 'left',
                overflow: 'hidden'
            });
            this.header.innerHTML = title;

            // content
            this.content = this.doc.createElement('div');
            this.content.innerHTML = msg;

            // footer
            this.footer = this.doc.createElement('div');
            XUI.setStyle(this.footer, {
                padding: '10px 10px',
                textAlign: 'right'
            });

            // button
            this.cancelButton = this.doc.createElement('span');
            this.okButton = this.doc.createElement('span');

            this.cancelButton.innerHTML = conf.cancelButtonText;
            this.cancelButton.setAttribute('data-role', 'cancel');
            this.okButton.innerHTML = conf.okButtonText;
            this.okButton.setAttribute('data-role', 'ok');

            var style = {
                boxSizing: 'border-box',
                display: 'inline-block',
                height: '30px',
                lineHeight: '30px',
                padding: '0 15px',
                textAlign: 'center',
                cursor: 'pointer',
                borderRadius: '5px'
            };
            var okButtonStyle = null;
            var cancelButtonStyle = null;
            if(null !== conf.cancelButtonStyle) {
                cancelButtonStyle = this.extend({}, style);
                cancelButtonStyle = this.extend(cancelButtonStyle, conf.cancelButtonStyle);
                XUI.setStyle(this.cancelButton, cancelButtonStyle);
            } else {
                XUI.setStyle(this.cancelButton, style);
                XUI.setStyle(this.cancelButton, {
                    color: '#7fbbe2',
                    marginRight: '5px',
                    border: '1px solid #7fbbe2',
                    backgroundColor: '#fff'
                });
            }

            if(null !== conf.okButtonStyle) {
                okButtonStyle = this.extend({}, style);
                okButtonStyle = this.extend(okButtonStyle, conf.okButtonStyle);
                XUI.setStyle(this.okButton, okButtonStyle);
            } else {
                XUI.setStyle(this.okButton, style);
                XUI.setStyle(this.okButton, {
                    color: '#fff',
                    border: '1px solid #7fbbe2',
                    backgroundColor: '#7fbbe2'
                });
            }

            // structure
            if(XDialog.BTN_CANCEL === type || (XDialog.BTN_CANCEL | XDialog.BTN_OK) === type) {
                this.footer.appendChild(this.cancelButton);
            }
            if(XDialog.BTN_OK === type || (XDialog.BTN_CANCEL | XDialog.BTN_OK) === type) {
                this.footer.appendChild(this.okButton);
            }

            this.wrapper.appendChild(this.closeButton);
            this.wrapper.appendChild(this.header);
            this.wrapper.appendChild(this.content);

            if(XDialog.BTN_NONE !== type) {
                this.wrapper.appendChild(this.footer);
            }
        },
        setCallback: function(callback) {
            this.callback = undefined !== callback ? callback : null;
        },
        resetPosition: function() {
            var _self = this;
            var width = this.wrapper.clientWidth;
            var winWidth = this.doc.body.clientWidth;

            this.wrapper.style.left = Math.floor((winWidth - width) / 2) + 'px';

            setTimeout(function(){
                var doc = _self.doc;
                var wrapper = _self.wrapper;
                var totalHeight = doc.defaultView.innerHeight || doc.documentElement.clientHeight;

                wrapper.style.top = Math.round(
                    (totalHeight - wrapper.clientHeight) * 0.5 * 0.6) + 'px';

                wrapper = null;
                doc = null;
                _self = null;
            }, 10);
        },
        render: function() {
            XUI.lock.lock();

            if(null === this.doc.getElementById(this.id)) {
                this.doc.body.appendChild(this.wrapper);
            }
        },
        bindEvent: function() {
            var _self = this;
            this.wrapper.onclick = function(e) {
                var target = e.target;

                if('ok' === target.getAttribute('data-role')) {
                    // 回调返回 false 不关闭弹窗
                    if(null === _self.callback || false !== _self.callback(1)) {
                        _self.close();
                    }

                    return;
                }

                if('cancel' === target.getAttribute('data-role')) {
                    if(null === _self.callback || false !== _self.callback(0)) {
                        _self.close();
                    }

                    return;
                }

                if('close' === target.getAttribute('data-role')) {
                    _self.close();

                    return;
                }

                // handler click
                if(null !== _self.onContentClick) {
                    _self.onContentClick(e);
                }
            };
        },
        unBindEvent: function() {
            this.wrapper.onclick = null;
        },

        // api
        alert: function(msg, title, callback) {
            this.setCallback(callback);

            this.init(
                '<div style="padding: 20px 20px">'+ msg +'</div>',
                title,
                XDialog.BTN_OK);

            this.render();
            this.resetPosition();
            this.bindEvent();
        },
        confirm: function(msg, title, callback) {
            this.setCallback(callback);

            this.init(
                '<div style="padding: 20px 20px">'+ msg +'</div>',
                title,
                XDialog.BTN_OK | XDialog.BTN_CANCEL);

            this.render();
            this.resetPosition();
            this.bindEvent();
        },
        show: function(content, title, configs) {
            this.init(content, title, XDialog.BTN_NONE, configs);

            this.render();
            this.bindEvent();
            this.resetPosition();
        },
        showWithBtn: function(content, title, btn, configs, callback) {
            this.setCallback(callback);

            this.init(content, title, btn, configs);

            this.render();
            this.bindEvent();
            this.resetPosition();
        },
        close: function() {
            var wrapper = this.doc.getElementById(this.id);
            if(null !== wrapper) {
                this.doc.body.removeChild(wrapper);
            }

            this.unBindEvent();

            this.wrapper = null;
            this.content = null;
            this.footer = null;
            this.cancelButton = null;
            this.okButton = null;
            this.closeButton = null;

            XUI.lock.unLock();
        }
    };

    XUI.BTN_OK = XDialog.BTN_OK;
    XUI.BTN_CANCEL = XDialog.BTN_CANCEL;
    XUI.BTN_NONE = XDialog.BTN_NONE;

    return new XDialog();
}();

})(window);
